#include "stdafx.h"
#include "PacketAnalyzer.h"
#include "binaryReader.h"
#include "BinaryWriter.h"
#include <malloc.h>
#include <math.h>

static const char PACKET_START_FLAG = 0xAA;

static PacketAnalyzController gCtrl;
static const char gPacketStartFlag[] = { 0xAA };


static void ReceiveData(PacketAnalyzController *pCtrl);




static char ReadByte(PacketAnalyzController *pCtrl)
{
	return pCtrl->buffer[pCtrl->index];
}
static char* GetAddress(PacketAnalyzController *pCtrl)
{
	return &pCtrl->buffer[pCtrl->index];
}
static int RemainBytes(PacketAnalyzController *pCtrl)
{
	return (pCtrl->length - pCtrl->index);
}
static bool Next(PacketAnalyzController *pCtrl)
{
	if (pCtrl->index >= pCtrl->length)
		return false;
	else if (pCtrl->index == pCtrl->length - 1)
	{
		pCtrl->index++;
		return false;
	}
	
	pCtrl->index++;
	return true;
}
static bool IsReadEnd(PacketAnalyzController *pCtrl)
{
	if (pCtrl->index >= pCtrl->length)
		return true;
	else
		return false;
}

static void CheckPacketBegin(PacketAnalyzController *pCtrl)
{
	char ch;

	while (true)
	{
		ch = ReadByte(pCtrl);
		if (PACKET_START_FLAG == ch)
		{
			Next(pCtrl);
			pCtrl->status = ANALYZER_STATUS_RECEIVING;
			pCtrl->addFunc = ReceiveData;
			return;
		}

		if (Next(pCtrl) == false)
			return;
	}

}

static void ReceiveData(PacketAnalyzController *pCtrl)
{
	PacketReceiveController* ctrl = &pCtrl->rcvCtrl;
	int remain;
	int readCount;
	if (ctrl->isAvailable == false)
	{
		int length;
		int ret;
		BinaryReaderControl binCtrl;
		BinaryReaderInit(GetAddress(pCtrl), RemainBytes(pCtrl), &binCtrl);
		ret = BinaryReaderGetInt(&binCtrl, &ctrl->packetLength);
		if (ctrl->buffer != NULL)
		{
			free(ctrl->buffer);
			ctrl->buffer = NULL;
		}

		pCtrl->index += 4;
		ctrl->index = 0;
		ctrl->buffer = (char *)malloc(ctrl->packetLength);
		ctrl->isAvailable = true;
	}
	remain = ctrl->packetLength - ctrl->index;
	readCount = min((remain), RemainBytes(pCtrl));
	memcpy(ctrl->buffer + ctrl->index, GetAddress(pCtrl), readCount);
	ctrl->index += readCount;
	pCtrl->index += readCount;

	if (ctrl->index >= ctrl->packetLength)
	{
		pCtrl->status = ANALYZER_STATUS_NONE;
		pCtrl->addFunc = CheckPacketBegin;
		ctrl->isAvailable = false;
	}
		
}

void ModeRun(PacketAnalyzController *pCtrl)
{
	while (IsReadEnd(pCtrl) == false)
	{
		pCtrl->addFunc(pCtrl);
	}
}

//==================================================
void PacketAnalyzerInit(PacketAnalyzController *pCtrl)
{
	memset(pCtrl, 0, sizeof(PacketAnalyzController));
	pCtrl->addFunc = CheckPacketBegin;
}

void PacketAnalyzerClose(PacketAnalyzController *pCtrl)
{
	if (pCtrl->buffer != NULL)
		free(pCtrl->buffer);
}

int PacketAnalyzerAddData(PacketAnalyzController *pCtrl, char* buffer, int length, Packet *packet)
{
	PacketReceiveController* rcvCtrl = &pCtrl->rcvCtrl;
	pCtrl->buffer = buffer;
	pCtrl->index = 0;
	pCtrl->length = length;

	ModeRun(pCtrl);
	if ((rcvCtrl->packetLength != 0) && (rcvCtrl->index == rcvCtrl->packetLength) )
	{
		packet->buffer = rcvCtrl->buffer;
		packet->length = rcvCtrl->packetLength;
		return 1;
	}
	return 0;
}

int PacketAnalyzerSetHeader(Packet *packet, char** buffer, int *length )
{
	BinaryWriterControl ctrl;

	BinaryWriter_Init(&ctrl, packet->buffer, packet->length);
	BinaryWriter_SetByte(&ctrl, PACKET_START_FLAG);
	BinaryWriter_SetInt(&ctrl, packet->length-5);
	*buffer = packet->buffer;
	*length = packet->length;
	
	return 0;
}